#!/usr/bin/python3
# -*- coding: UTF-8 -*-

# Python内建了map()和reduce()函数

# map()函数接收两个参数，一个是函数，一个是Iterable，map将传入的函数依次作用到序列的每个元素，
# 并把结果作为新的Iterator返回

# 有一个函数f(x)=x2，要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上，就可以用map()实现
def f(x):
    return x * x
r = map(f, [1, 2, 3, 4, 5, 6])
print(list(r))

# 把数字转换成字符串
print(list(map(str, [1,2,3,4,5,6,7])))

# reduce把一个函数作用在一个序列[x1, x2, x3, ...]上，这个函数必须接收两个参数，
# reduce把结果继续和序列的下一个元素做累积计算:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
def add(x, y):
    return x + y
print(reduce(add, [1, 2,3,4,5]))

# 求和运算可以直接用Python内建函数sum()，没必要动用reduce
# 如果要把序列[1, 3, 5, 7, 9]变换成整数13579，reduce就可以派上用场
def compin(x,y):
    return x * 10 + y
print(reduce(compin, [1,2,3,4,5,6]))


# 定义一个str2int的函数
def str2int(s):
    def fn(x,y):
        return x * 10 + y
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    return reduce(fn, map(char2num,s))
print(str2int('58745'))

# 用lambda函数进一步简化
def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
def str2int1(s):
    return reduce(lambda x,y: x * 10 + y, map(char2num, s))
print(str2int1('85475'))

# int函数可以直接转换字符串为数字
print(int('545'))

# 利用map()函数，把用户输入的不规范的英文名字，变为首字母大写，
# 其他小写的规范名字。输入：['adam', 'LISA', 'barT']，输出：['Adam', 'Lisa', 'Bart']
def yw2u(s):
    return s[0:1].upper() + s[1:].lower()

print(list(map(yw2u, ['adam', 'LISA', 'barT'])))

# 编写乘法函数prod
def prod(lists):
    def fn(x,y):
        return x * y
    return reduce(fn, lists)

print('3 * 5 * 7 * 9 =', prod([2,5,7,9]))

# 利用map和reduce编写一个str2float函数，把字符串'123.456'转换成浮点数123.456
def str2float(s):
    ss = s.split('.')
    def fn (x,y):
        return x * 10 + y
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    return reduce(fn, map(char2num, ss[0] + ss[1]))/10**len(ss[1])

print(str2float('123.25'))

def prod1(lists):
    return  reduce(lambda x,y:x*y, lists)

print(prod1([2,5,6]))


def str2float1(s):
    return reduce(lambda x,y : x*10 + y, map())


# 定义序列，根据输入的英文名转换首字母大写，其它小写
def in2up():
    while True:
        n = input('输入英文名:')
        yield n[0:1].upper() + n[1:].lower()

n = 0
for k in in2up():
    print(k)
    n = n + 1
    if n == 3:
        break

